home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / termsorc.lha / Extras / Source / term-source.lha / termTransfer.c < prev    next >
C/C++ Source or Header  |  1995-09-26  |  59KB  |  2,824 lines

  1. /*
  2. **    termTransfer.c
  3. **
  4. **    File transfer routines
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* The action strings to display. */
  13.  
  14. STATIC STRPTR    SendQuery[3],
  15.         ReceiveQuery[3],
  16.         TransferTypes[3];
  17.  
  18.     /* CreateArgName(STRPTR String):
  19.      *
  20.      *    Create another node based upon a string given.
  21.      *    Encloses parameters in quotes if necessary and
  22.      *    `escapes' quotes.
  23.      */
  24.  
  25. STATIC struct Node * __regargs
  26. CreateArgName(STRPTR String)
  27. {
  28.     struct Node    *Node;
  29.     STRPTR         Index = String;
  30.     LONG         Len,NewLen;
  31.     BOOLEAN      Quotes = FALSE;
  32.  
  33.     Len = NewLen = strlen(String);
  34.  
  35.     while(*Index)
  36.     {
  37.         if(*Index == '\"')
  38.             NewLen++;
  39.  
  40.         if(*Index == ' ' && !Quotes)
  41.         {
  42.             NewLen += 2;
  43.  
  44.             Quotes = TRUE;
  45.         }
  46.  
  47.         Index++;
  48.     }
  49.  
  50.     if(!Len)
  51.     {
  52.         NewLen += 2;
  53.  
  54.         Quotes = TRUE;
  55.     }
  56.  
  57.     if(NewLen > Len)
  58.     {
  59.         if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + NewLen + 1,MEMF_ANY))
  60.         {
  61.             STRPTR Dest;
  62.  
  63.             Node -> ln_Name = (STRPTR)(Node + 1);
  64.  
  65.             Dest    = Node -> ln_Name;
  66.             Index    = String;
  67.  
  68.             if(Quotes)
  69.                 *Dest++ = '\"';
  70.  
  71.             while(*Index)
  72.             {
  73.                 if(*Index == '\"')
  74.                     *Dest++ = '*';
  75.  
  76.                 *Dest++ = *Index++;
  77.             }
  78.  
  79.             if(Quotes)
  80.                 *Dest++ = '\"';
  81.  
  82.             *Dest = 0;
  83.         }
  84.     }
  85.     else
  86.     {
  87.         if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + Len + 1,MEMF_ANY))
  88.             strcpy(Node -> ln_Name = (STRPTR)(Node + 1),String);
  89.     }
  90.  
  91.     return(Node);
  92. }
  93.  
  94.     /* BuildString():
  95.      *
  96.      *    Build a command line based upon a template and
  97.      *    existing file transfer info.
  98.      */
  99.  
  100. STATIC STRPTR __regargs
  101. BuildString(STRPTR Source,STRPTR From,STRPTR To,BYTE Type,BOOLEAN ReceiveMode,STRPTR SingleFile,struct FileTransferInfo *Info,LONG *Error)
  102. {
  103.     struct List    *List;
  104.     STRPTR         Result = NULL;
  105.  
  106.     if(Info)
  107.     {
  108.         if(Info -> FileList . mlh_Head -> mln_Succ)
  109.             Info -> CurrentFile = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  110.         else
  111.             Info = NULL;
  112.     }
  113.  
  114.     *Error = 0;
  115.  
  116.     if(List = CreateList())
  117.     {
  118.         struct Node        *Node;
  119.         UBYTE             LocalBuffer[MAX_FILENAME_LENGTH],
  120.                      TempBuffer[MAX_FILENAME_LENGTH];
  121.         STRPTR             Index = Source,
  122.                      Dest = LocalBuffer;
  123.         struct FileRequester    *FileRequest;
  124.  
  125.         while(*Index && !(*Error))
  126.         {
  127.             if(*Index == '%')
  128.             {
  129.                 struct Node    *InsertHere = List -> lh_TailPred;
  130.                 BOOLEAN      InsertBefore = TRUE;
  131.  
  132.                 Index++;
  133.  
  134.                 if(!(*Index))
  135.                 {
  136.                     *Dest = 0;
  137.  
  138.                     if(LocalBuffer[0])
  139.                     {
  140.                         if(Node = CreateNode(LocalBuffer))
  141.                         {
  142.                             AddTail(List,Node);
  143.  
  144.                             LocalBuffer[0] = 0;
  145.                         }
  146.                         else
  147.                             *Error = ERR_NO_MEM;
  148.                     }
  149.  
  150.                     break;
  151.                 }
  152.  
  153.                 switch(*Index)
  154.                 {
  155.                     case 'f':
  156.  
  157.                         if(SingleFile)
  158.                         {
  159.                             if(Node = CreateArgName(SingleFile))
  160.                                 AddTail(List,Node);
  161.                             else
  162.                                 *Error = ERR_NO_MEM;
  163.  
  164.                             SingleFile = NULL;
  165.  
  166.                             break;
  167.                         }
  168.  
  169.                         if(Info)
  170.                         {
  171.                             if(Node = CreateArgName(Info -> CurrentFile -> Name))
  172.                                 AddTail(List,Node);
  173.                             else
  174.                                 *Error = ERR_NO_MEM;
  175.  
  176.                             if(Info -> CurrentFile -> Node . mln_Succ)
  177.                                 Info -> CurrentFile = (struct FileTransferNode *)Info -> CurrentFile -> Node . mln_Succ;
  178.                             else
  179.                                 Info = NULL;
  180.  
  181.                             break;
  182.                         }
  183.  
  184.                         LT_LockWindow(Window);
  185.  
  186.                         if(ReceiveMode)
  187.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),To,"",TempBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE);
  188.                         else
  189.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),From,"",TempBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),FALSE);
  190.  
  191.                         if(FileRequest)
  192.                         {
  193.                             if(Node = CreateArgName(TempBuffer))
  194.                                 AddTail(List,Node);
  195.                             else
  196.                                 *Error = ERR_NO_MEM;
  197.  
  198.                             FreeAslRequest(FileRequest);
  199.                         }
  200.                         else
  201.                             *Error = ERR_ABORTED;
  202.  
  203.                         LT_UnlockWindow(Window);
  204.  
  205.                         break;
  206.  
  207.                     case 'F':
  208.  
  209.                         if(SingleFile)
  210.                         {
  211.                             if(Node = CreateArgName(FilePart(SingleFile)))
  212.                                 AddTail(List,Node);
  213.                             else
  214.                                 *Error = ERR_NO_MEM;
  215.  
  216.                             SingleFile = NULL;
  217.  
  218.                             break;
  219.                         }
  220.  
  221.                         if(Info)
  222.                         {
  223.                             if(Node = CreateArgName(FilePart(Info -> CurrentFile -> Name)))
  224.                                 AddTail(List,Node);
  225.                             else
  226.                                 *Error = ERR_NO_MEM;
  227.  
  228.                             if(Info -> CurrentFile -> Node . mln_Succ)
  229.                                 Info -> CurrentFile = (struct FileTransferNode *)Info -> CurrentFile -> Node . mln_Succ;
  230.                             else
  231.                                 Info = NULL;
  232.  
  233.                             break;
  234.                         }
  235.  
  236.                         LT_LockWindow(Window);
  237.  
  238.                         if(ReceiveMode)
  239.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),To,"",TempBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE);
  240.                         else
  241.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),From,"",TempBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),FALSE);
  242.  
  243.                         if(FileRequest)
  244.                         {
  245.                             if(Node = CreateArgName(FilePart(TempBuffer)))
  246.                                 AddTail(List,Node);
  247.                             else
  248.                                 *Error = ERR_NO_MEM;
  249.  
  250.                             FreeAslRequest(FileRequest);
  251.                         }
  252.                         else
  253.                             *Error = ERR_ABORTED;
  254.  
  255.                         LT_UnlockWindow(Window);
  256.  
  257.                         break;
  258.  
  259.                     case 'm':
  260.  
  261.                         if(SingleFile)
  262.                         {
  263.                             if(Node = CreateArgName(SingleFile))
  264.                                 AddTail(List,Node);
  265.                             else
  266.                                 *Error = ERR_NO_MEM;
  267.  
  268.                             SingleFile = NULL;
  269.  
  270.                             break;
  271.                         }
  272.  
  273.                         if(Info)
  274.                         {
  275.                             struct FileTransferNode *SomeNode = Info -> CurrentFile;
  276.  
  277.                             while(SomeNode -> Node . mln_Succ && !(*Error))
  278.                             {
  279.                                 if(Node = CreateArgName(SomeNode -> Name))
  280.                                     AddTail(List,Node);
  281.                                 else
  282.                                     *Error = ERR_NO_MEM;
  283.  
  284.                                 SomeNode = (struct FileTransferNode *)SomeNode -> Node . mln_Succ;
  285.                             }
  286.  
  287.                             Info = NULL;
  288.  
  289.                             break;
  290.                         }
  291.  
  292.                         LT_LockWindow(Window);
  293.  
  294.                         TempBuffer[0] = 0;
  295.  
  296.                         if(ReceiveMode)
  297.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),To,"",TempBuffer,NULL,TRUE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE);
  298.                         else
  299.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),From,"",TempBuffer,NULL,FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),FALSE);
  300.  
  301.                         LT_UnlockWindow(Window);
  302.  
  303.                         if(FileRequest)
  304.                         {
  305.                             LONG i;
  306.  
  307.                             if(TempBuffer[0] && FileRequest -> fr_NumArgs == 1)
  308.                             {
  309.                                 if(Node = CreateArgName(TempBuffer))
  310.                                 {
  311.                                     AddTail(List,Node);
  312.  
  313.                                     break;
  314.                                 }
  315.                                 else
  316.                                     *Error = ERR_NO_MEM;
  317.                             }
  318.  
  319.                             for(i = 0 ; i < FileRequest -> fr_NumArgs && !(*Error) ; i++)
  320.                             {
  321.                                 if(FileRequest -> fr_ArgList[i] . wa_Lock)
  322.                                 {
  323.                                     if(NameFromLock(FileRequest -> fr_ArgList[i] . wa_Lock,TempBuffer,MAX_FILENAME_LENGTH))
  324.                                     {
  325.                                         if(AddPart(TempBuffer,FileRequest -> fr_ArgList[i] . wa_Name,MAX_FILENAME_LENGTH))
  326.                                         {
  327.                                             if(Node = CreateArgName(TempBuffer))
  328.                                                 AddTail(List,Node);
  329.                                             else
  330.                                                 *Error = ERR_NO_MEM;
  331.                                         }
  332.                                         else
  333.                                             *Error = IoErr();
  334.                                     }
  335.                                     else
  336.                                         *Error = IoErr();
  337.                                 }
  338.                                 else
  339.                                 {
  340.                                     strcpy(TempBuffer,FileRequest -> fr_Drawer);
  341.  
  342.                                     if(AddPart(TempBuffer,FileRequest -> fr_ArgList[i] . wa_Name,MAX_FILENAME_LENGTH))
  343.                                     {
  344.                                         if(Node = CreateArgName(TempBuffer))
  345.                                             AddTail(List,Node);
  346.                                         else
  347.                                             *Error = ERR_NO_MEM;
  348.                                     }
  349.                                     else
  350.                                         *Error = IoErr();
  351.                                 }
  352.                             }
  353.  
  354.                             FreeAslRequest(FileRequest);
  355.                         }
  356.                         else
  357.                             *Error = ERR_ABORTED;
  358.  
  359.                         break;
  360.  
  361.                     case 'M':
  362.  
  363.                         if(SingleFile)
  364.                         {
  365.                             if(Node = CreateArgName(FilePart(SingleFile)))
  366.                                 AddTail(List,Node);
  367.                             else
  368.                                 *Error = ERR_NO_MEM;
  369.  
  370.                             SingleFile = NULL;
  371.  
  372.                             break;
  373.                         }
  374.  
  375.                         if(Info)
  376.                         {
  377.                             struct FileTransferNode *SomeNode = Info -> CurrentFile;
  378.  
  379.                             while(SomeNode -> Node . mln_Succ && !(*Error))
  380.                             {
  381.                                 if(Node = CreateArgName(FilePart(SomeNode -> Name)))
  382.                                     AddTail(List,Node);
  383.                                 else
  384.                                     *Error = ERR_NO_MEM;
  385.  
  386.                                 SomeNode = (struct FileTransferNode *)SomeNode -> Node . mln_Succ;
  387.                             }
  388.  
  389.                             Info = NULL;
  390.  
  391.                             break;
  392.                         }
  393.  
  394.                         LT_LockWindow(Window);
  395.  
  396.                         TempBuffer[0] = 0;
  397.  
  398.                         if(ReceiveMode)
  399.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),To,"",TempBuffer,NULL,TRUE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE);
  400.                         else
  401.                             FileRequest = GetFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),From,"",TempBuffer,NULL,FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),FALSE);
  402.  
  403.                         LT_UnlockWindow(Window);
  404.  
  405.                         if(FileRequest)
  406.                         {
  407.                             LONG i;
  408.  
  409.                             if(TempBuffer[0] && FileRequest -> fr_NumArgs == 1)
  410.                             {
  411.                                 if(Node = CreateArgName(FilePart(TempBuffer)))
  412.                                 {
  413.                                     AddTail(List,Node);
  414.  
  415.                                     break;
  416.                                 }
  417.                                 else
  418.                                     *Error = ERR_NO_MEM;
  419.                             }
  420.  
  421.                             for(i = 0 ; i < FileRequest -> fr_NumArgs && !(*Error) ; i++)
  422.                             {
  423.                                 if(FileRequest -> fr_ArgList[i] . wa_Lock)
  424.                                 {
  425.                                     if(AddPart(TempBuffer,FileRequest -> fr_ArgList[i] . wa_Name,MAX_FILENAME_LENGTH))
  426.                                     {
  427.                                         if(Node = CreateArgName(TempBuffer))
  428.                                             AddTail(List,Node);
  429.                                         else
  430.                                             *Error = ERR_NO_MEM;
  431.                                     }
  432.                                     else
  433.                                         *Error = IoErr();
  434.                                 }
  435.                                 else
  436.                                 {
  437.                                     if(Node = CreateArgName(FileRequest -> fr_ArgList[i] . wa_Name))
  438.                                         AddTail(List,Node);
  439.                                     else
  440.                                         *Error = ERR_NO_MEM;
  441.                                 }
  442.                             }
  443.  
  444.                             FreeAslRequest(FileRequest);
  445.                         }
  446.                         else
  447.                             *Error = ERR_ABORTED;
  448.  
  449.                         break;
  450.  
  451.                     case 'b':
  452.                     case 'B':
  453.  
  454.                         SPrintf(SharedBuffer,"%ld",Config -> SerialConfig -> BaudRate);
  455.  
  456.                         if(Node = CreateNode(SharedBuffer))
  457.                             AddTail(List,Node);
  458.                         else
  459.                             *Error = ERR_NO_MEM;
  460.  
  461.                         break;
  462.  
  463.                     case 'c':
  464.                     case 'C':
  465.  
  466.                         SPrintf(SharedBuffer,"%ld",DTERate ? DTERate : Config -> SerialConfig -> BaudRate);
  467.  
  468.                         if(Node = CreateNode(SharedBuffer))
  469.                             AddTail(List,Node);
  470.                         else
  471.                             *Error = ERR_NO_MEM;
  472.  
  473.                         break;
  474.  
  475.                     case 'p':
  476.                     case 'P':
  477.  
  478.                         if(Node = CreateArgName(RexxPortName))
  479.                             AddTail(List,Node);
  480.                         else
  481.                             *Error = ERR_NO_MEM;
  482.  
  483.                         break;
  484.  
  485.                     case 'd':
  486.                     case 'D':
  487.  
  488.                         if(Node = CreateArgName(Config -> SerialConfig -> SerialDevice))
  489.                             AddTail(List,Node);
  490.                         else
  491.                             *Error = ERR_NO_MEM;
  492.  
  493.                         break;
  494.  
  495.                     case 'u':
  496.                     case 'U':
  497.  
  498.                         SPrintf(SharedBuffer,"%ld",Config -> SerialConfig -> UnitNumber);
  499.  
  500.                         if(Node = CreateNode(SharedBuffer))
  501.                             AddTail(List,Node);
  502.                         else
  503.                             *Error = ERR_NO_MEM;
  504.  
  505.                         break;
  506.  
  507.                     case '<':
  508.  
  509.                         if(Node = CreateArgName(From))
  510.                             AddTail(List,Node);
  511.                         else
  512.                             *Error = ERR_NO_MEM;
  513.  
  514.                         break;
  515.  
  516.                     case '>':
  517.  
  518.                         if(Node = CreateArgName(To))
  519.                             AddTail(List,Node);
  520.                         else
  521.                             *Error = ERR_NO_MEM;
  522.  
  523.                         break;
  524.  
  525.                     case 's':
  526.                     case 'S':
  527.  
  528.                         if(!GetPubScreenName(Window -> WScreen,SharedBuffer))
  529.                             SharedBuffer[0] = 0;
  530.  
  531.                         if(Node = CreateArgName(SharedBuffer))
  532.                             AddTail(List,Node);
  533.                         else
  534.                             *Error = ERR_NO_MEM;
  535.  
  536.                         break;
  537.  
  538.                     default:
  539.  
  540.                         *Dest = *Index;
  541.  
  542.                         InsertBefore = FALSE;
  543.  
  544.                         break;
  545.                 }
  546.  
  547.                 if(InsertBefore && Node)
  548.                 {
  549.                     struct Node *OtherNode;
  550.  
  551.                     *Dest = 0;
  552.  
  553.                     if(LocalBuffer[0])
  554.                     {
  555.                         if(OtherNode = CreateNode(LocalBuffer))
  556.                         {
  557.                             Insert(List,OtherNode,InsertHere);
  558.  
  559.                             LocalBuffer[0] = 0;
  560.                         }
  561.                         else
  562.                             *Error = ERR_NO_MEM;
  563.                     }
  564.  
  565.                     Dest = LocalBuffer;
  566.                 }
  567.             }
  568.             else
  569.                 *Dest++ = *Index;
  570.  
  571.             Index++;
  572.         }
  573.  
  574.         *Dest = 0;
  575.  
  576.         if(LocalBuffer[0] && !(*Error))
  577.         {
  578.             if(Node = CreateNode(LocalBuffer))
  579.                 AddTail(List,Node);
  580.             else
  581.                 *Error = ERR_NO_MEM;
  582.         }
  583.  
  584.         if(!(*Error))
  585.         {
  586.             if(List -> lh_Head -> ln_Succ)
  587.             {
  588.                 LONG Total = 0,Len;
  589.  
  590.                 for(Node = List -> lh_Head ; Node -> ln_Succ ; Node = Node -> ln_Succ)
  591.                     Total += strlen(Node -> ln_Name) + 1;
  592.  
  593.                 if(Result = (STRPTR)AllocVecPooled(Total,MEMF_ANY))
  594.                 {
  595.                     STRPTR Buffer = Result;
  596.  
  597.                     for(Node = List -> lh_Head ; Node -> ln_Succ ; Node = Node -> ln_Succ)
  598.                     {
  599.                         Len = strlen(Node -> ln_Name);
  600.  
  601.                         memcpy(Buffer,Node -> ln_Name,Len);
  602.  
  603.                         Buffer += Len;
  604.  
  605.                         *Buffer++ = ' ';
  606.                     }
  607.  
  608.                     Buffer[-1] = 0;
  609.                 }
  610.             }
  611.             else
  612.                 Result = "";
  613.         }
  614.  
  615.         DeleteList(List);
  616.     }
  617.     else
  618.         *Error = ERR_NO_MEM;
  619.  
  620.     return(Result);
  621. }
  622.  
  623.     /* ReplaceName(STRPTR Original):
  624.      *
  625.      *    Replace a filename with a mangled version for
  626.      *    file uploads.
  627.      */
  628.  
  629. STATIC STRPTR __regargs
  630. ReplaceName(STRPTR Source)
  631. {
  632.     if(Config -> TransferConfig -> MangleFileNames)
  633.     {
  634.         UBYTE LocalName[MAX_FILENAME_LENGTH],*Char;
  635.  
  636.         strcpy(OriginalName,Source);
  637.  
  638.         ShrinkName(FilePart(Source),LocalName,12,TRUE);
  639.  
  640.         strcpy(ShrunkenName,Source);
  641.  
  642.         Char = PathPart(ShrunkenName);
  643.  
  644.         *Char = 0;
  645.  
  646.         AddPart(ShrunkenName,LocalName,MAX_FILENAME_LENGTH);
  647.  
  648.         return(ShrunkenName);
  649.     }
  650.     else
  651.     {
  652.         OriginalName[0] = 0;
  653.  
  654.         return(Source);
  655.     }
  656. }
  657.  
  658.     /* FreeFileTransferInfo(struct FileTransferInfo *Info):
  659.      *
  660.      *    Free a file transfer info list as allocated
  661.      *    by AllocFileTransferInfo() and AddFileTransferNode().
  662.      */
  663.  
  664. VOID __regargs
  665. FreeFileTransferInfo(struct FileTransferInfo *Info)
  666. {
  667.     if(Info)
  668.     {
  669.         struct FileTransferNode *Node,
  670.                     *Next;
  671.  
  672.         Node = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  673.  
  674.         while(Next = (struct FileTransferNode *)Node -> Node . mln_Succ)
  675.         {
  676.             FreeVecPooled(Node);
  677.  
  678.             Node = Next;
  679.         }
  680.  
  681.         FreeVecPooled(Info);
  682.     }
  683. }
  684.  
  685.     /* AllocFileTransferInfo():
  686.      *
  687.      *    Allocate a FileTransferInfo structure for use with
  688.      *    AddFileTransferNode().
  689.      */
  690.  
  691. struct FileTransferInfo *
  692. AllocFileTransferInfo()
  693. {
  694.     struct FileTransferInfo *Info;
  695.  
  696.     if(Info = (struct FileTransferInfo *)AllocVecPooled(sizeof(struct FileTransferInfo),MEMF_ANY | MEMF_CLEAR))
  697.     {
  698.         NewList((struct List *)&Info -> FileList);
  699.  
  700.         return(Info);
  701.     }
  702.  
  703.     return(NULL);
  704. }
  705.  
  706.     /* AddFileTransferNode(struct FileTransferInfo *Info,STRPTR Name,ULONG Size):
  707.      *
  708.      *    Allocate a file transfer information node.
  709.      */
  710.  
  711. BYTE __regargs
  712. AddFileTransferNode(struct FileTransferInfo *Info,STRPTR Name,ULONG Size)
  713. {
  714.     struct FileTransferNode *Node;
  715.     WORD             Len = strlen(Name) + 1;
  716.  
  717.     if(Node = (struct FileTransferNode *)AllocVecPooled(sizeof(struct FileTransferNode) + Len,MEMF_ANY))
  718.     {
  719.         Node -> Size    = Size;
  720.         Node -> Name    = (STRPTR)(Node + 1);
  721.  
  722.         strcpy(Node -> Name,Name);
  723.  
  724.         AddTail((struct List *)&Info -> FileList,(struct Node *)Node);
  725.  
  726.         Info -> TotalSize += Size;
  727.  
  728.         Info -> TotalFiles++;
  729.  
  730.         return(TRUE);
  731.     }
  732.     else
  733.         return(FALSE);
  734. }
  735.  
  736.     /* Compare(struct FileTransferNode **A,struct FileTransferNode **B):
  737.      *
  738.      *    Local subroutine required by qsort().
  739.      */
  740.  
  741. STATIC int __stdargs
  742. Compare(struct FileTransferNode **A,struct FileTransferNode **B)
  743. {
  744.     return(Strcoll(FilePart((*A) -> Name),FilePart((*B) -> Name)));
  745. }
  746.  
  747.     /* SortFileTransferInfo(struct FileTransferInfo *Info):
  748.      *
  749.      *    Sorts the file transfer information list in ascending
  750.      *    order, but makes sure that the files are sorted
  751.      *    in descending order (i.e. the larger files come
  752.      *    first and files of equal size are sorted
  753.      *    lexically).
  754.      */
  755.  
  756. VOID __regargs
  757. SortFileTransferInfo(struct FileTransferInfo *Info)
  758. {
  759.     if(Info -> TotalFiles > 1)
  760.     {
  761.         struct FileTransferNode **NodeList;
  762.  
  763.         if(NodeList = (struct FileTransferNode **)AllocVecPooled(sizeof(struct FileTransferNode *) * Info -> TotalFiles,MEMF_ANY))
  764.         {
  765.             struct FileTransferNode *Node;
  766.             LONG             i = 0;
  767.  
  768.             for(Node = (struct FileTransferNode *)Info -> FileList . mlh_Head ; Node -> Node . mln_Succ ; Node = (struct FileTransferNode *)Node -> Node . mln_Succ)
  769.                 NodeList[i++] = Node;
  770.  
  771.             qsort((APTR)NodeList,Info -> TotalFiles,sizeof(struct FileTransferNode *),Compare);
  772.  
  773.             NewList((struct List *)&Info -> FileList);
  774.  
  775.             for(i = 0 ; i < Info -> TotalFiles ; i++)
  776.                 AddTail((struct List *)&Info -> FileList,(struct Node *)&NodeList[i] -> Node);
  777.  
  778.             FreeVecPooled(NodeList);
  779.         }
  780.     }
  781.  
  782.     Info -> DoneSize    = 0;
  783.     Info -> DoneFiles    = 0;
  784.  
  785.     Info -> CurrentFile    = (struct FileTransferNode *)Info -> FileList . mlh_Head;
  786.     Info -> CurrentSize    = Info -> CurrentFile -> Size;
  787. }
  788.  
  789.     /* BuildFileTransferInfo(struct FileRequester *FileRequester):
  790.      *
  791.      *    Build a file transfer information list from
  792.      *    information provided by a FileRequester structure.
  793.      */
  794.  
  795. struct FileTransferInfo * __regargs
  796. BuildFileTransferInfo(struct FileRequester *FileRequester)
  797. {
  798.     struct FileTransferInfo *Info;
  799.     LONG             FilesFound = 0;
  800.  
  801.     if(Info = AllocFileTransferInfo())
  802.     {
  803.         BYTE    Success = FALSE;
  804.         BPTR    NewLock,
  805.             OldLock;
  806.  
  807.         if(NewLock = Lock(FileRequester -> fr_Drawer,ACCESS_READ))
  808.         {
  809.             OldLock = CurrentDir(NewLock);
  810.  
  811.             if(FileRequester -> fr_NumArgs)
  812.             {
  813.                 struct FileInfoBlock *FileInfo;
  814.  
  815.                 if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  816.                 {
  817.                     BPTR         FileLock;
  818.                     struct WBArg    *ArgList = FileRequester -> fr_ArgList;
  819.                     LONG         i;
  820.  
  821.                     Success = TRUE;
  822.  
  823.                     for(i = 0 ; Success && i < FileRequester -> fr_NumArgs ; i++)
  824.                     {
  825.                         if(ArgList[i] . wa_Name)
  826.                         {
  827.                             if(ArgList[i] . wa_Lock)
  828.                             {
  829.                                 CurrentDir(ArgList[i] . wa_Lock);
  830.  
  831.                                 if(FileLock = Lock(ArgList[i] . wa_Name,ACCESS_READ))
  832.                                 {
  833.                                     if(Examine(FileLock,FileInfo))
  834.                                     {
  835.                                         if(FileInfo -> fib_DirEntryType < 0)
  836.                                         {
  837.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  838.                                             {
  839.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  840.                                                     Success = FALSE;
  841.                                                 else
  842.                                                     FilesFound++;
  843.                                             }
  844.                                         }
  845.                                     }
  846.  
  847.                                     UnLock(FileLock);
  848.                                 }
  849.  
  850.                                 CurrentDir(NewLock);
  851.                             }
  852.                             else
  853.                             {
  854.                                 if(FileLock = Lock(ArgList[i] . wa_Name,ACCESS_READ))
  855.                                 {
  856.                                     if(Examine(FileLock,FileInfo))
  857.                                     {
  858.                                         if(FileInfo -> fib_DirEntryType < 0)
  859.                                         {
  860.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  861.                                             {
  862.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  863.                                                     Success = FALSE;
  864.                                                 else
  865.                                                     FilesFound++;
  866.                                             }
  867.                                         }
  868.                                     }
  869.  
  870.                                     UnLock(FileLock);
  871.                                 }
  872.                             }
  873.                         }
  874.                     }
  875.                 }
  876.  
  877.                 FreeDosObject(DOS_FIB,FileInfo);
  878.             }
  879.             else
  880.             {
  881.                 struct AnchorPath *Anchor;
  882.  
  883.                 STRPTR FileName;
  884.  
  885.                 if(FileRequester -> fr_NumArgs > 1 && FileRequester -> fr_ArgList)
  886.                     FileName = FileRequester -> fr_ArgList -> wa_Name;
  887.                 else
  888.                     FileName = FileRequester -> fr_File;
  889.  
  890.                 if(Anchor = (struct AnchorPath *)AllocVecPooled(sizeof(struct AnchorPath),MEMF_ANY | MEMF_CLEAR))
  891.                 {
  892.                     if(!MatchFirst(FileName,Anchor))
  893.                     {
  894.                         Success = TRUE;
  895.  
  896.                         if(Anchor -> ap_Info . fib_DirEntryType < 0)
  897.                         {
  898.                             if(NameFromLock(NewLock,SharedBuffer,512))
  899.                             {
  900.                                 if(AddPart(SharedBuffer,Anchor -> ap_Info . fib_FileName,512))
  901.                                 {
  902.                                     if(!AddFileTransferNode(Info,SharedBuffer,Anchor -> ap_Info . fib_Size))
  903.                                         Success = FALSE;
  904.                                     else
  905.                                         FilesFound++;
  906.                                 }
  907.                             }
  908.                         }
  909.  
  910.                         if(Success)
  911.                         {
  912.                             while(!MatchNext(Anchor))
  913.                             {
  914.                                 if(NameFromLock(NewLock,SharedBuffer,512))
  915.                                 {
  916.                                     if(AddPart(SharedBuffer,Anchor -> ap_Info . fib_FileName,512))
  917.                                     {
  918.                                         if(!AddFileTransferNode(Info,SharedBuffer,Anchor -> ap_Info . fib_Size))
  919.                                         {
  920.                                             Success = FALSE;
  921.  
  922.                                             break;
  923.                                         }
  924.                                         else
  925.                                             FilesFound++;
  926.                                     }
  927.                                 }
  928.                             }
  929.                         }
  930.  
  931.                         if(IoErr() != ERROR_NO_MORE_ENTRIES)
  932.                             Success = FALSE;
  933.                     }
  934.  
  935.                     MatchEnd(Anchor);
  936.  
  937.                     FreeVecPooled(Anchor);
  938.                 }
  939.             }
  940.  
  941.             CurrentDir(OldLock);
  942.  
  943.             UnLock(NewLock);
  944.         }
  945.  
  946.         if(Success && FilesFound)
  947.         {
  948.             SortFileTransferInfo(Info);
  949.  
  950.             return(Info);
  951.         }
  952.         else
  953.             FreeFileTransferInfo(Info);
  954.     }
  955.  
  956.     return(NULL);
  957. }
  958.  
  959.     /* SendTextFile(STRPTR TheFile):
  960.      *
  961.      *    Send a single text file via xpr.
  962.      */
  963.  
  964. VOID __regargs
  965. SendTextFile(BYTE Type,STRPTR TheFile)
  966. {
  967.     STRPTR    From,To,Name;
  968.     BYTE    Mode;
  969.  
  970.     TheFile = ReplaceName(TheFile);
  971.  
  972.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> ASCIIUploadType == XFER_INTERNAL)
  973.     {
  974.         InternalASCIIUpload(TheFile,TRUE);
  975.  
  976.         return;
  977.     }
  978.  
  979.     switch(Type)
  980.     {
  981.         case TRANSFER_BINARY:
  982.  
  983.             Name    = Config -> TransferConfig -> BinaryUploadLibrary;
  984.             Mode    = Config -> TransferConfig -> BinaryUploadType;
  985.             From    = Config -> PathConfig -> BinaryUploadPath;
  986.             To    = Config -> PathConfig -> BinaryDownloadPath;
  987.             break;
  988.  
  989.         case TRANSFER_TEXT:
  990.  
  991.             Name    = Config -> TransferConfig -> TextUploadLibrary;
  992.             Mode    = Config -> TransferConfig -> TextUploadType;
  993.             From    = Config -> PathConfig -> TextUploadPath;
  994.             To    = Config -> PathConfig -> TextDownloadPath;
  995.             break;
  996.  
  997.         case TRANSFER_ASCII:
  998.  
  999.             Name    = Config -> TransferConfig -> ASCIIUploadLibrary;
  1000.             Mode    = Config -> TransferConfig -> ASCIIUploadType;
  1001.             From    = Config -> PathConfig -> ASCIIUploadPath;
  1002.             To    = Config -> PathConfig -> ASCIIDownloadPath;
  1003.             break;
  1004.     }
  1005.  
  1006.     if(Mode == XFER_DEFAULT && Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  1007.     {
  1008.         Name    = Config -> TransferConfig -> DefaultLibrary;
  1009.         Mode    = XFER_EXTERNALPROGRAM;
  1010.     }
  1011.  
  1012.     if(Mode == XFER_EXTERNALPROGRAM)
  1013.     {
  1014.         STRPTR    String;
  1015.         LONG    Error;
  1016.  
  1017.         BlockWindows();
  1018.  
  1019.         if(String = BuildString(Name,From,To,Type,FALSE,TheFile,NULL,&Error))
  1020.         {
  1021.             ClearSerial();
  1022.  
  1023.             LaunchCommand(String);
  1024.  
  1025.             RestartSerial();
  1026.  
  1027.             FreeVecPooled(String);
  1028.         }
  1029.  
  1030.         ReleaseWindows();
  1031.     }
  1032.     else
  1033.     {
  1034.         BYTE OldStatus = Status;
  1035.         BPTR NewDir,OldDir;
  1036.  
  1037.         if(Type == TRANSFER_ASCII)
  1038.             NewDir = Lock(Config -> PathConfig -> ASCIIUploadPath,ACCESS_READ);
  1039.         else
  1040.             NewDir = Lock(Config -> PathConfig -> TextUploadPath,ACCESS_READ);
  1041.  
  1042.         if(NewDir)
  1043.             OldDir = CurrentDir(NewDir);
  1044.         else
  1045.             OldDir = NULL;
  1046.  
  1047.         Uploading = TRUE;
  1048.  
  1049.         LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
  1050.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1051.  
  1052.             /* If not initialized, try to set up a new
  1053.              * external transfer protocol.
  1054.              */
  1055.  
  1056.         if(!XProtocolBase)
  1057.         {
  1058.             if(SelectProtocol(LastXprLibrary,Window))
  1059.             {
  1060.                 if(ProtocolSetup(FALSE))
  1061.                     SaveProtocolOpts();
  1062.             }
  1063.         }
  1064.  
  1065.         if(XProtocolBase)
  1066.         {
  1067.             SetTransferMenu(TRUE);
  1068.  
  1069.             XprIO -> xpr_filename = TheFile;
  1070.  
  1071.             if(TransferPanel(SendQuery[TRANSFER_TEXT]))
  1072.             {
  1073.                 Status = STATUS_UPLOAD;
  1074.  
  1075. #ifdef ASYNC_XPR_SREAD
  1076.                 ClearSerial();
  1077. #endif
  1078.                 LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[TRANSFER_TEXT]);
  1079.  
  1080.                 if(ReadRequest && WriteRequest)
  1081.                 {
  1082.                     if(XProtocolSend(XprIO))
  1083.                         TransferFailed = FALSE;
  1084.                     else
  1085.                         TransferFailed = TRUE;
  1086.                 }
  1087.                 else
  1088.                     TransferFailed = TRUE;
  1089.  
  1090.                 if(TransferFailed || TransferAborted)
  1091.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1092.                 else
  1093.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1094.  
  1095.                 if(TransferFailed || TransferError)
  1096.                 {
  1097.                     if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1098.                         WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1099.  
  1100.                     DeleteTransferPanel(TRUE);
  1101.                 }
  1102.                 else
  1103.                 {
  1104.                     if(TransferWindow)
  1105.                     {
  1106.                         if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1107.                             WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1108.  
  1109.                         WaitTime(2,0);
  1110.                     }
  1111.  
  1112.                     DeleteTransferPanel(FALSE);
  1113.                 }
  1114.  
  1115.                 Status = OldStatus;
  1116. #ifdef ASYNC_XPR_SREAD
  1117.                 RestartSerial();
  1118. #endif
  1119.             }
  1120.         }
  1121.         else
  1122.             SetTransferMenu(TRUE);
  1123.  
  1124.         if(OldDir)
  1125.             CurrentDir(OldDir);
  1126.  
  1127.         if(NewDir)
  1128.             UnLock(NewDir);
  1129.  
  1130.         if(SendAbort && UsesZModem)
  1131.             SerWrite(ZModemCancel,20);
  1132.  
  1133.         SendAbort = FALSE;
  1134.  
  1135.         Uploading = FALSE;
  1136.  
  1137.         if(Config -> CommandConfig -> UploadMacro[0])
  1138.             SerialCommand(Config -> CommandConfig -> UploadMacro);
  1139.  
  1140.         DidTransfer = FALSE;
  1141.     }
  1142. }
  1143.  
  1144.     /* StartXprReceive():
  1145.      *
  1146.      *    Receive files via xpr.
  1147.      */
  1148.  
  1149. VOID __regargs
  1150. StartXprReceive(BYTE Type,STRPTR Name,BYTE WaitForIt)
  1151. {
  1152.     STRPTR    From,To,Cmd;
  1153.     BYTE    Mode;
  1154.  
  1155.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> ASCIIDownloadType == XFER_INTERNAL)
  1156.     {
  1157.         InternalASCIIDownload(Name,WaitForIt);
  1158.  
  1159.         return;
  1160.     }
  1161.  
  1162.     switch(Type)
  1163.     {
  1164.         case TRANSFER_BINARY:
  1165.  
  1166.             Cmd    = Config -> TransferConfig -> BinaryDownloadLibrary;
  1167.             Mode    = Config -> TransferConfig -> BinaryDownloadType;
  1168.             From    = Config -> PathConfig -> BinaryUploadPath;
  1169.             To    = Config -> PathConfig -> BinaryDownloadPath;
  1170.             break;
  1171.  
  1172.         case TRANSFER_TEXT:
  1173.  
  1174.             Cmd    = Config -> TransferConfig -> TextDownloadLibrary;
  1175.             Mode    = Config -> TransferConfig -> TextDownloadType;
  1176.             From    = Config -> PathConfig -> TextUploadPath;
  1177.             To    = Config -> PathConfig -> TextDownloadPath;
  1178.             break;
  1179.  
  1180.         case TRANSFER_ASCII:
  1181.  
  1182.             Cmd    = Config -> TransferConfig -> ASCIIDownloadLibrary;
  1183.             Mode    = Config -> TransferConfig -> ASCIIDownloadType;
  1184.             From    = Config -> PathConfig -> ASCIIUploadPath;
  1185.             To    = Config -> PathConfig -> ASCIIDownloadPath;
  1186.             break;
  1187.     }
  1188.  
  1189.     if(Mode == XFER_DEFAULT && Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  1190.     {
  1191.         Cmd    = Config -> TransferConfig -> DefaultLibrary;
  1192.         Mode    = XFER_EXTERNALPROGRAM;
  1193.     }
  1194.  
  1195.     if(Mode == XFER_EXTERNALPROGRAM)
  1196.     {
  1197.         STRPTR    String;
  1198.         LONG    Error;
  1199.  
  1200.         BlockWindows();
  1201.  
  1202.         if(String = BuildString(Cmd,From,To,Type,TRUE,Name,NULL,&Error))
  1203.         {
  1204.             ClearSerial();
  1205.  
  1206.             LaunchCommand(String);
  1207.  
  1208.             RestartSerial();
  1209.  
  1210.             FreeVecPooled(String);
  1211.         }
  1212.  
  1213.         ReleaseWindows();
  1214.     }
  1215.     else
  1216.     {
  1217.         struct FileRequester    *FileRequest;
  1218.         UBYTE             DummyBuffer[MAX_FILENAME_LENGTH];
  1219.         BYTE             OldStatus = Status;
  1220.         BPTR             NewDir = NULL,
  1221.                      OldDir = NULL;
  1222.  
  1223.         DB(kprintf("[ receiver\n"));
  1224.         DB(kprintf("[ cleargenericlist\n"));
  1225.  
  1226.         ClearGenericList(GenericListTable[GLIST_DOWNLOAD]);
  1227.  
  1228.         LocalizeString(ReceiveQuery,MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT,MSG_TERMTRANSFER_DOWNLOAD_ASCII_TXT);
  1229.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1230.  
  1231.             /* Select the download path. */
  1232.  
  1233.         switch(Type)
  1234.         {
  1235.             case TRANSFER_BINARY:
  1236.  
  1237.                 DownloadPath = Config -> PathConfig -> BinaryDownloadPath;
  1238.                 break;
  1239.  
  1240.             case TRANSFER_TEXT:
  1241.  
  1242.                 DownloadPath = Config -> PathConfig -> TextDownloadPath;
  1243.                 break;
  1244.  
  1245.             case TRANSFER_ASCII:
  1246.  
  1247.                 DownloadPath = Config -> PathConfig -> ASCIIDownloadPath;
  1248.                 break;
  1249.         }
  1250.  
  1251.         DB(kprintf("[ doing path\n"));
  1252.  
  1253.         if(DownloadPath[0])
  1254.         {
  1255.             if(NewDir = Lock(DownloadPath,ACCESS_READ))
  1256.                 OldDir = CurrentDir(NewDir);
  1257.         }
  1258.  
  1259.         DB(kprintf("[ blockwindows\n"));
  1260.         BlockWindows();
  1261.  
  1262.             /* Set up the library if necessary. */
  1263.  
  1264.         if(!XProtocolBase)
  1265.         {
  1266.             DB(kprintf("[ selectprotocol\n"));
  1267.             if(SelectProtocol(LastXprLibrary,Window))
  1268.             {
  1269.                 DB(kprintf("[ protocolsetup\n"));
  1270.                 if(ProtocolSetup(FALSE))
  1271.                     SaveProtocolOpts();
  1272.             }
  1273.         }
  1274.  
  1275.         if(XProtocolBase)
  1276.         {
  1277.             DB(kprintf("[ settransfermenu"));
  1278.             SetTransferMenu(TRUE);
  1279.  
  1280.                 /* Do we need to ask the user for
  1281.                  * the destination file name?
  1282.                  */
  1283.  
  1284.             if(TransferBits & XPRS_NORECREQ)
  1285.             {
  1286.                 DB(kprintf("[ no filerequester\n"));
  1287.  
  1288.                     /* Obviously not, let's open
  1289.                      * the transfer info window as
  1290.                      * usual and download the file(s).
  1291.                      */
  1292.  
  1293.                 DB(kprintf("[ transferpanel\n"));
  1294.                 if(TransferPanel(ReceiveQuery[Type]))
  1295.                 {
  1296.                     Status = STATUS_DOWNLOAD;
  1297. #ifdef ASYNC_XPR_SREAD
  1298.                     DB(kprintf("[ clearserial\n"));
  1299.                     ClearSerial();
  1300. #endif
  1301.                     LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),TransferTypes[Type]);
  1302.  
  1303.                         /* Receive the data. */
  1304.  
  1305.                     if(ReadRequest && WriteRequest)
  1306.                     {
  1307.                         DB(kprintf("[ going in\n"));
  1308.                         if(XProtocolReceive(XprIO))
  1309.                             TransferFailed = FALSE;
  1310.                         else
  1311.                             TransferFailed = TRUE;
  1312.                     }
  1313.                     else
  1314.                         TransferFailed = TRUE;
  1315.  
  1316.                         /* In case the transfer has been aborted,
  1317.                          * flush the input buffer of dirty data.
  1318.                          */
  1319.  
  1320.                     if(TransferAborted)
  1321.                     {
  1322.                         DB(kprintf("[ xpr_sflush()\n"));
  1323.                         xpr_sflush();
  1324.                     }
  1325.  
  1326.                     if(TransferAborted || TransferFailed)
  1327.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1328.                     else
  1329.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1330.  
  1331.                     if(TransferFailed || TransferError)
  1332.                     {
  1333.                         DB(kprintf("[ wakeup\n"));
  1334.                         if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1335.                             WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1336.  
  1337.                         DB(kprintf("[ deletetransferpanel %ld\n",WaitForIt));
  1338.                         DeleteTransferPanel(WaitForIt);
  1339.                     }
  1340.                     else
  1341.                     {
  1342.                         if(TransferWindow)
  1343.                         {
  1344.                             DB(kprintf("[ wakeup\n"));
  1345.                             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1346.                                 WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1347.  
  1348.                             DB(kprintf("[ waittime\n"));
  1349.                             WaitTime(2,0);
  1350.                         }
  1351.  
  1352.                         DB(kprintf("[ deletetransferpanel false\n"));
  1353.                         DeleteTransferPanel(FALSE);
  1354.                     }
  1355.  
  1356.                     Status = OldStatus;
  1357.  
  1358.                         /* Queue another read request. */
  1359. #ifdef ASYNC_XPR_SREAD
  1360.                     DB(kprintf("[ restartserial\n"));
  1361.                     RestartSerial();
  1362. #endif
  1363.                 }
  1364.             }
  1365.             else
  1366.             {
  1367.                 if(!Name)
  1368.                 {
  1369.                     if(FileRequest = GetFile(Window,ReceiveQuery[Type],DownloadPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),TRUE))
  1370.                     {
  1371.                             /* Save the download path. */
  1372.  
  1373.                         strcpy(DownloadPath,FileRequest -> fr_Drawer);
  1374.  
  1375.                         ConfigChanged = TRUE;
  1376.  
  1377.                             /* Install the name of the file to receive. */
  1378.  
  1379.                         XprIO -> xpr_filename = DummyBuffer;
  1380.  
  1381.                         FreeAslRequest(FileRequest);
  1382.  
  1383.                         Name = DummyBuffer;
  1384.                     }
  1385.                 }
  1386.                 else
  1387.                 {
  1388.                     STRPTR Index;
  1389.  
  1390.                     strcpy(DownloadPath,Name);
  1391.  
  1392.                     ConfigChanged = TRUE;
  1393.  
  1394.                     Index = PathPart(DownloadPath);
  1395.  
  1396.                     *Index = 0;
  1397.  
  1398.                     XprIO -> xpr_filename = Name;
  1399.                 }
  1400.  
  1401.                     /* Download the file(s). */
  1402.  
  1403.                 if(Name)
  1404.                 {
  1405.                         /* Open the transfer panel. */
  1406.  
  1407.                     if(TransferPanel(ReceiveQuery[Type]))
  1408.                     {
  1409.                         Status = STATUS_DOWNLOAD;
  1410. #ifdef ASYNC_XPR_SREAD
  1411.                         ClearSerial();
  1412. #endif
  1413.                         LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),TransferTypes[Type]);
  1414.  
  1415.                             /* Receive the file. */
  1416.  
  1417.                         if(ReadRequest && WriteRequest)
  1418.                         {
  1419.                             if(XProtocolReceive(XprIO))
  1420.                                 TransferFailed = FALSE;
  1421.                             else
  1422.                                 TransferFailed = TRUE;
  1423.                         }
  1424.                         else
  1425.                             TransferFailed = TRUE;
  1426.  
  1427.                             /* In case the transfer has been aborted,
  1428.                              * flush the input buffer of dirty data.
  1429.                              */
  1430.  
  1431.                         if(TransferAborted)
  1432.                             xpr_sflush();
  1433.  
  1434.                         if(TransferAborted || TransferFailed)
  1435.                             Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1436.                         else
  1437.                             Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1438.  
  1439.                         if(TransferFailed || TransferError)
  1440.                         {
  1441.                             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1442.                                 WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1443.  
  1444.                             DeleteTransferPanel(WaitForIt);
  1445.                         }
  1446.                         else
  1447.                         {
  1448.                             if(TransferWindow)
  1449.                             {
  1450.                                 if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1451.                                     WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1452.  
  1453.                                 WaitTime(2,0);
  1454.                             }
  1455.  
  1456.                             DeleteTransferPanel(FALSE);
  1457.                         }
  1458.  
  1459.                         Status = OldStatus;
  1460.  
  1461.                             /* Queue another read
  1462.                              * request.
  1463.                              */
  1464. #ifdef ASYNC_XPR_SREAD
  1465.                         RestartSerial();
  1466. #endif
  1467.                     }
  1468.                 }
  1469.             }
  1470.         }
  1471.         else
  1472.             SetTransferMenu(TRUE);
  1473.  
  1474.         DB(kprintf("[ olddir\n"));
  1475.         if(OldDir)
  1476.             CurrentDir(OldDir);
  1477.  
  1478.         DB(kprintf("[ newdir\n"));
  1479.         if(NewDir)
  1480.             UnLock(NewDir);
  1481.  
  1482.         DB(kprintf("[ zmodemcancel\n"));
  1483.         if(SendAbort && UsesZModem)
  1484.             SerWrite(ZModemCancel,20);
  1485.  
  1486.         SendAbort = FALSE;
  1487.  
  1488.         DB(kprintf("[ releasewindows\n"));
  1489.         ReleaseWindows();
  1490.  
  1491.         DownloadPath = NULL;
  1492.  
  1493.         DidTransfer = FALSE;
  1494.  
  1495.         if(WaitForIt)
  1496.         {
  1497.             DB(kprintf("[ downloadmacro\n"));
  1498.             if(Config -> CommandConfig -> DownloadMacro[0])
  1499.                 SerialCommand(Config -> CommandConfig -> DownloadMacro);
  1500.         }
  1501.  
  1502.         DB(kprintf("[ finished.\n"));
  1503.     }
  1504. }
  1505.  
  1506.     /* StartXprSend():
  1507.      *
  1508.      *    Send files via xpr.
  1509.      */
  1510.  
  1511. BYTE __regargs
  1512. StartXprSend(BYTE Type,BYTE WaitForIt)
  1513. {
  1514.     STRPTR    From,To,Name;
  1515.     BYTE    Mode;
  1516.  
  1517.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> ASCIIDownloadType == XFER_INTERNAL)
  1518.         return(InternalASCIIUpload(NULL,WaitForIt));
  1519.  
  1520.     switch(Type)
  1521.     {
  1522.         case TRANSFER_BINARY:
  1523.  
  1524.             Name    = Config -> TransferConfig -> BinaryUploadLibrary;
  1525.             Mode    = Config -> TransferConfig -> BinaryUploadType;
  1526.             From    = Config -> PathConfig -> BinaryUploadPath;
  1527.             To    = Config -> PathConfig -> BinaryDownloadPath;
  1528.             break;
  1529.  
  1530.         case TRANSFER_TEXT:
  1531.  
  1532.             Name    = Config -> TransferConfig -> TextUploadLibrary;
  1533.             Mode    = Config -> TransferConfig -> TextUploadType;
  1534.             From    = Config -> PathConfig -> TextUploadPath;
  1535.             To    = Config -> PathConfig -> TextDownloadPath;
  1536.             break;
  1537.  
  1538.         case TRANSFER_ASCII:
  1539.  
  1540.             Name    = Config -> TransferConfig -> ASCIIUploadLibrary;
  1541.             Mode    = Config -> TransferConfig -> ASCIIUploadType;
  1542.             From    = Config -> PathConfig -> ASCIIUploadPath;
  1543.             To    = Config -> PathConfig -> ASCIIDownloadPath;
  1544.             break;
  1545.     }
  1546.  
  1547.     if(Mode == XFER_DEFAULT && Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  1548.     {
  1549.         Name    = Config -> TransferConfig -> DefaultLibrary;
  1550.         Mode    = XFER_EXTERNALPROGRAM;
  1551.     }
  1552.  
  1553.     if(Mode == XFER_EXTERNALPROGRAM)
  1554.     {
  1555.         STRPTR    String;
  1556.         LONG    Error;
  1557.         BYTE    Result;
  1558.  
  1559.         BlockWindows();
  1560.  
  1561.         if(String = BuildString(Name,From,To,Type,FALSE,NULL,NULL,&Error))
  1562.         {
  1563.             ClearSerial();
  1564.  
  1565.             if(LaunchCommand(String))
  1566.                 Result = FALSE;
  1567.             else
  1568.                 Result = TRUE;
  1569.  
  1570.             RestartSerial();
  1571.  
  1572.             FreeVecPooled(String);
  1573.         }
  1574.         else
  1575.             Result = FALSE;
  1576.  
  1577.         ReleaseWindows();
  1578.  
  1579.         return(Result);
  1580.     }
  1581.     else
  1582.     {
  1583.         struct FileRequester    *FileRequest;
  1584.         UBYTE             DummyBuffer[MAX_FILENAME_LENGTH];
  1585.         BYTE             OldStatus = Status;
  1586.         STRPTR             UploadPath;
  1587.         BYTE             DidSend = TRUE;
  1588.         BPTR             NewDir = NULL,
  1589.                      OldDir = NULL;
  1590.  
  1591.         LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
  1592.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1593.  
  1594.             /* We are uploading data. */
  1595.  
  1596.         Uploading = TRUE;
  1597.  
  1598.             /* Select the upload path. */
  1599.  
  1600.         switch(Type)
  1601.         {
  1602.             case TRANSFER_BINARY:
  1603.  
  1604.                 UploadPath = Config -> PathConfig -> BinaryUploadPath;
  1605.                 break;
  1606.  
  1607.             case TRANSFER_TEXT:
  1608.  
  1609.                 UploadPath = Config -> PathConfig -> TextUploadPath;
  1610.                 break;
  1611.  
  1612.             case TRANSFER_ASCII:
  1613.  
  1614.                 UploadPath = Config -> PathConfig -> ASCIIUploadPath;
  1615.                 break;
  1616.         }
  1617.  
  1618.         DB(kprintf("-> sender\n"));
  1619.  
  1620.         if(UploadPath[0])
  1621.         {
  1622.             if(NewDir = Lock(UploadPath,ACCESS_READ))
  1623.                 OldDir = CurrentDir(NewDir);
  1624.         }
  1625.  
  1626.         DB(kprintf("-> blockwindows\n"));
  1627.         BlockWindows();
  1628.  
  1629.             /* If not initialized, try to set up a new
  1630.              * external transfer protocol.
  1631.              */
  1632.  
  1633.         DB(kprintf("-> xprotocolbase 0x%08lx\n",XProtocolBase));
  1634.         if(!XProtocolBase)
  1635.         {
  1636.             if(SelectProtocol(LastXprLibrary,Window))
  1637.             {
  1638.                 if(ProtocolSetup(FALSE))
  1639.                     SaveProtocolOpts();
  1640.             }
  1641.         }
  1642.  
  1643.         if(XProtocolBase)
  1644.         {
  1645.             DB(kprintf("-> SetTransfermenu\n"));
  1646.             SetTransferMenu(TRUE);
  1647.  
  1648.                 /* Do we need to use our own file requester or
  1649.                  * will xpr handle this job for us?
  1650.                  */
  1651.  
  1652.             if(TransferBits & XPRS_NOSNDREQ)
  1653.             {
  1654.                 DB(kprintf("-> no file requester\n"));
  1655.  
  1656.                     /* Open the transfer info window. */
  1657.  
  1658.                 DB(kprintf("-> transferpanel\n"));
  1659.                 if(TransferPanel(SendQuery[Type]))
  1660.                 {
  1661.                     Status = STATUS_UPLOAD;
  1662.  
  1663.                         /* Shut up the serial line. */
  1664. #ifdef ASYNC_XPR_SREAD
  1665.                     DB(kprintf("-> clearserial\n"));
  1666.                     ClearSerial();
  1667. #endif
  1668.                     LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
  1669.  
  1670.                         /* Perform upload. */
  1671.  
  1672.                     if(ReadRequest && WriteRequest)
  1673.                     {
  1674.                         DB(kprintf("-> going in\n"));
  1675.                         if(XProtocolSend(XprIO))
  1676.                             TransferFailed = FALSE;
  1677.                         else
  1678.                             TransferFailed = TRUE;
  1679.                     }
  1680.                     else
  1681.                         TransferFailed = TRUE;
  1682.  
  1683.                     if(TransferFailed || TransferAborted)
  1684.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1685.                     else
  1686.                         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1687.  
  1688.                     if(TransferFailed || TransferError)
  1689.                     {
  1690.                         DB(kprintf("-> waking up\n"));
  1691.                         if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1692.                             WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1693.  
  1694.                         DB(kprintf("-> deletetransferpanel %ld\n",WaitForIt));
  1695.                         DeleteTransferPanel(WaitForIt);
  1696.                     }
  1697.                     else
  1698.                     {
  1699.                         if(TransferWindow)
  1700.                         {
  1701.                             DB(kprintf("-> waking up\n"));
  1702.                             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1703.                                 WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1704.  
  1705.                             DB(kprintf("-> waiting a bit\n"));
  1706.                             WaitTime(2,0);
  1707.                         }
  1708.  
  1709.                         DB(kprintf("-> deletetransferpanel false\n"));
  1710.                         DeleteTransferPanel(FALSE);
  1711.                     }
  1712.  
  1713.                     Status = OldStatus;
  1714.  
  1715.                         /* And request another character. */
  1716. #ifdef ASYNC_XPR_SREAD
  1717.                     DB(kprintf("->restartserial\n"));
  1718.                     RestartSerial();
  1719. #endif
  1720.                 }
  1721.             }
  1722.             else
  1723.             {
  1724.                     /* We will need the file requester to find
  1725.                      * out which file(s) are to be transferred.
  1726.                      * Multiple files and wildcards are
  1727.                      * supported as well as plain file names.
  1728.                      */
  1729.  
  1730.                 if(FileRequest = GetFile(Window,SendQuery[Type],UploadPath,"",DummyBuffer,"",FALSE,TRUE,FALSE,LocaleString(MSG_TERMTRANSFER_SEND_TXT),TRUE))
  1731.                 {
  1732.                     strcpy(UploadPath,FileRequest -> fr_Drawer);
  1733.  
  1734.                     ConfigChanged = TRUE;
  1735.  
  1736.                     if(FileTransferInfo = BuildFileTransferInfo(FileRequest))
  1737.                     {
  1738.                             /* Make sure that at least the
  1739.                              * first file gets transferred
  1740.                              * in case the protocol does
  1741.                              * no support batch upload.
  1742.                              */
  1743.  
  1744.                         XprIO -> xpr_filename = ReplaceName(FileTransferInfo -> CurrentFile -> Name);
  1745.  
  1746.                         if(TransferPanel(SendQuery[Type]))
  1747.                         {
  1748.                             Status = STATUS_UPLOAD;
  1749. #ifdef ASYNC_XPR_SREAD
  1750.                             ClearSerial();
  1751. #endif
  1752.                             LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
  1753.  
  1754.                             if(ReadRequest && WriteRequest)
  1755.                             {
  1756.                                 if(XProtocolSend(XprIO))
  1757.                                     TransferFailed = FALSE;
  1758.                                 else
  1759.                                     TransferFailed = TRUE;
  1760.                             }
  1761.                             else
  1762.                                 TransferFailed = TRUE;
  1763.  
  1764.                             if(TransferFailed || TransferAborted)
  1765.                                 Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  1766.                             else
  1767.                                 Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1768.  
  1769.                             if(TransferFailed || TransferError)
  1770.                             {
  1771.                                 if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1772.                                     WakeUp(TransferWindow,SOUND_BADTRANSFER);
  1773.  
  1774.                                 DeleteTransferPanel(WaitForIt);
  1775.                             }
  1776.                             else
  1777.                             {
  1778.                                 if(TransferWindow)
  1779.                                 {
  1780.                                     if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  1781.                                         WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  1782.  
  1783.                                     WaitTime(2,0);
  1784.                                 }
  1785.  
  1786.                                 DeleteTransferPanel(FALSE);
  1787.                             }
  1788.  
  1789.                             Status = OldStatus;
  1790. #ifdef ASYNC_XPR_SREAD
  1791.                             RestartSerial();
  1792. #endif
  1793.                         }
  1794.                         else
  1795.                             MyEasyRequest(Window,LocaleString(MSG_TERMTRANSFER_FAILED_TO_LOCATE_DIRECTORY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FileRequest -> fr_Drawer);
  1796.  
  1797.                         if(FileTransferInfo)
  1798.                         {
  1799.                             FreeFileTransferInfo(FileTransferInfo);
  1800.  
  1801.                             FileTransferInfo = NULL;
  1802.                         }
  1803.                     }
  1804.  
  1805.                     FreeAslRequest(FileRequest);
  1806.                 }
  1807.                 else
  1808.                     DidSend = FALSE;
  1809.             }
  1810.         }
  1811.         else
  1812.             SetTransferMenu(TRUE);
  1813.  
  1814.         DB(kprintf("-> olddir\n"));
  1815.         if(OldDir)
  1816.             CurrentDir(OldDir);
  1817.  
  1818.         DB(kprintf("-> newdir\n"));
  1819.         if(NewDir)
  1820.             UnLock(NewDir);
  1821.  
  1822.         DB(kprintf("-> serwrite\n"));
  1823.         if(SendAbort && UsesZModem)
  1824.             SerWrite(ZModemCancel,20);
  1825.  
  1826.         SendAbort = FALSE;
  1827.  
  1828.         DB(kprintf("-> releasewindows\n"));
  1829.         ReleaseWindows();
  1830.  
  1831.         Uploading = FALSE;
  1832.  
  1833.         if(WaitForIt)
  1834.         {
  1835.             DB(kprintf("-> serialcommand\n"));
  1836.             if(Config -> CommandConfig -> UploadMacro[0])
  1837.                 SerialCommand(Config -> CommandConfig -> UploadMacro);
  1838.         }
  1839.  
  1840.         DidTransfer = FALSE;
  1841.  
  1842.         DB(kprintf("-> didsend %ld\n",DidSend));
  1843.         return(DidSend);
  1844.     }
  1845. }
  1846.  
  1847.     /* StartXprSendFromList():
  1848.      *
  1849.      *    Send files via xpr.
  1850.      */
  1851.  
  1852. BYTE __regargs
  1853. StartXprSendFromList(BYTE Type,BYTE WaitForIt)
  1854. {
  1855.     STRPTR    From,To,Name;
  1856.     BYTE    Mode;
  1857.  
  1858.     if(Type == TRANSFER_ASCII && Config -> TransferConfig -> ASCIIDownloadType == XFER_INTERNAL)
  1859.         return(InternalASCIIUpload(NULL,WaitForIt));
  1860.  
  1861.     switch(Type)
  1862.     {
  1863.         case TRANSFER_BINARY:
  1864.  
  1865.             Name    = Config -> TransferConfig -> BinaryUploadLibrary;
  1866.             Mode    = Config -> TransferConfig -> BinaryUploadType;
  1867.             From    = Config -> PathConfig -> BinaryUploadPath;
  1868.             To    = Config -> PathConfig -> BinaryDownloadPath;
  1869.             break;
  1870.  
  1871.         case TRANSFER_TEXT:
  1872.  
  1873.             Name    = Config -> TransferConfig -> TextUploadLibrary;
  1874.             Mode    = Config -> TransferConfig -> TextUploadType;
  1875.             From    = Config -> PathConfig -> TextUploadPath;
  1876.             To    = Config -> PathConfig -> TextDownloadPath;
  1877.             break;
  1878.  
  1879.         case TRANSFER_ASCII:
  1880.  
  1881.             Name    = Config -> TransferConfig -> ASCIIUploadLibrary;
  1882.             Mode    = Config -> TransferConfig -> ASCIIUploadType;
  1883.             From    = Config -> PathConfig -> ASCIIUploadPath;
  1884.             To    = Config -> PathConfig -> ASCIIDownloadPath;
  1885.             break;
  1886.     }
  1887.  
  1888.     if(Mode == XFER_DEFAULT && Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  1889.     {
  1890.         Name    = Config -> TransferConfig -> DefaultLibrary;
  1891.         Mode    = XFER_EXTERNALPROGRAM;
  1892.     }
  1893.  
  1894.     if(Mode == XFER_EXTERNALPROGRAM)
  1895.     {
  1896.         STRPTR    String;
  1897.         LONG    Error;
  1898.         BYTE    Result;
  1899.  
  1900.         BlockWindows();
  1901.  
  1902.         if(String = BuildString(Name,From,To,Type,FALSE,NULL,FileTransferInfo,&Error))
  1903.         {
  1904.             ClearSerial();
  1905.  
  1906.             if(LaunchCommand(String))
  1907.                 Result = FALSE;
  1908.             else
  1909.                 Result = TRUE;
  1910.  
  1911.             RestartSerial();
  1912.  
  1913.             FreeVecPooled(String);
  1914.         }
  1915.         else
  1916.             Result = FALSE;
  1917.  
  1918.         if(FileTransferInfo)
  1919.         {
  1920.             FreeFileTransferInfo(FileTransferInfo);
  1921.  
  1922.             FileTransferInfo = NULL;
  1923.         }
  1924.  
  1925.         ReleaseWindows();
  1926.  
  1927.         return(Result);
  1928.     }
  1929.     else
  1930.     {
  1931.         BYTE    OldStatus    = Status,
  1932.             DidSend     = TRUE;
  1933.         BPTR    NewDir        = NULL,
  1934.             OldDir;
  1935.         STRPTR    UploadPath;
  1936.  
  1937.         LocalizeString(SendQuery,MSG_TERMTRANSFER_UPLOAD_FILE_TXT,MSG_TERMTRANSFER_UPLOAD_ASCII_TXT);
  1938.         LocalizeString(TransferTypes,MSG_TERMTRANSFER_BINARY_TXT,MSG_TERMTRANSFER_ASCII_TXT);
  1939.  
  1940.             /* We are uploading data. */
  1941.  
  1942.         Uploading = TRUE;
  1943.  
  1944.         switch(Type)
  1945.         {
  1946.             case TRANSFER_BINARY:
  1947.  
  1948.                 UploadPath = Config -> PathConfig -> BinaryUploadPath;
  1949.                 break;
  1950.  
  1951.             case TRANSFER_TEXT:
  1952.  
  1953.                 UploadPath = Config -> PathConfig -> TextUploadPath;
  1954.                 break;
  1955.  
  1956.             case TRANSFER_ASCII:
  1957.  
  1958.                 UploadPath = Config -> PathConfig -> ASCIIUploadPath;
  1959.                 break;
  1960.         }
  1961.  
  1962.         if(UploadPath[0])
  1963.         {
  1964.             if(NewDir = Lock(UploadPath,ACCESS_READ))
  1965.                 OldDir = CurrentDir(NewDir);
  1966.         }
  1967.  
  1968.         BlockWindows();
  1969.  
  1970.             /* If not initialized, try to set up a new
  1971.              * external transfer protocol.
  1972.              */
  1973.  
  1974.         if(!XProtocolBase)
  1975.         {
  1976.             if(WaitForIt)
  1977.             {
  1978.                 if(SelectProtocol(LastXprLibrary,Window))
  1979.                 {
  1980.                     if(ProtocolSetup(FALSE))
  1981.                         SaveProtocolOpts();
  1982.                 }
  1983.             }
  1984.         }
  1985.  
  1986.         if(XProtocolBase)
  1987.         {
  1988.             SetTransferMenu(TRUE);
  1989.  
  1990.                 /* Make sure that at least the
  1991.                  * first file gets transferred
  1992.                  * in case the protocol does
  1993.                  * no support batch upload.
  1994.                  */
  1995.  
  1996.             XprIO -> xpr_filename = ReplaceName(FileTransferInfo -> CurrentFile -> Name);
  1997.  
  1998.             if(TransferPanel(SendQuery[Type]))
  1999.             {
  2000.                 Status = STATUS_UPLOAD;
  2001. #ifdef ASYNC_XPR_SREAD
  2002.                 ClearSerial();
  2003. #endif
  2004.                 LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),TransferTypes[Type]);
  2005.  
  2006.                 if(ReadRequest && WriteRequest)
  2007.                 {
  2008.                     DB(kprintf("going in\n"));
  2009.  
  2010.                     if(XProtocolSend(XprIO))
  2011.                         TransferFailed = FALSE;
  2012.                     else
  2013.                         TransferFailed = TRUE;
  2014.                 }
  2015.                 else
  2016.                     TransferFailed = TRUE;
  2017.  
  2018.                 DB(kprintf("ok, done\n"));
  2019.  
  2020.                 if(TransferFailed || TransferAborted)
  2021.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
  2022.                 else
  2023.                     Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  2024.  
  2025.                 DB(kprintf("cleaning up...\n"));
  2026.  
  2027.                 if(TransferFailed || TransferError)
  2028.                 {
  2029.                     if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2030.                         WakeUp(TransferWindow,SOUND_BADTRANSFER);
  2031.  
  2032.                     DeleteTransferPanel(WaitForIt);
  2033.                 }
  2034.                 else
  2035.                 {
  2036.                     if(TransferWindow)
  2037.                     {
  2038.                         if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2039.                             WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  2040.  
  2041.                         WaitTime(2,0);
  2042.                     }
  2043.  
  2044.                     DeleteTransferPanel(FALSE);
  2045.                 }
  2046.  
  2047.                 DB(kprintf("cleaned up\n"));
  2048.  
  2049.                 Status = OldStatus;
  2050. #ifdef ASYNC_XPR_SREAD
  2051.                 RestartSerial();
  2052. #endif
  2053.             }
  2054.  
  2055.             DB(kprintf("discarding filetransferinfo\n"));
  2056.  
  2057.             if(FileTransferInfo)
  2058.             {
  2059.                 FreeFileTransferInfo(FileTransferInfo);
  2060.  
  2061.                 FileTransferInfo = NULL;
  2062.             }
  2063.  
  2064.             DB(kprintf("did that\n"));
  2065.         }
  2066.         else
  2067.         {
  2068.             SetTransferMenu(TRUE);
  2069.  
  2070.             DidSend = FALSE;
  2071.         }
  2072.  
  2073.         DB(kprintf("now for the rest\n"));
  2074.  
  2075.         if(NewDir)
  2076.         {
  2077.             DB(kprintf("currentdir\n"));
  2078.             CurrentDir(OldDir);
  2079.             DB(kprintf("newdir\n"));
  2080.             UnLock(NewDir);
  2081.         }
  2082.  
  2083.         if(SendAbort && UsesZModem)
  2084.         {
  2085.             DB(kprintf("zmodemcancel\n"));
  2086.             SerWrite(ZModemCancel,20);
  2087.         }
  2088.  
  2089.         SendAbort = FALSE;
  2090.  
  2091.         DB(kprintf("releasewindows\n"));
  2092.         ReleaseWindows();
  2093.  
  2094.         Uploading = FALSE;
  2095.  
  2096.         if(WaitForIt)
  2097.         {
  2098.             if(Config -> CommandConfig -> UploadMacro[0])
  2099.             {
  2100.                 DB(kprintf("uploadmacro\n"));
  2101.                 SerialCommand(Config -> CommandConfig -> UploadMacro);
  2102.             }
  2103.         }
  2104.  
  2105.         DidTransfer = FALSE;
  2106.  
  2107.         DB(kprintf("through. didsend=%ld\n",DidSend));
  2108.  
  2109.         return(DidSend);
  2110.     }
  2111. }
  2112.  
  2113.     /* ChangeProtocol(STRPTR ProtocolName):
  2114.      *
  2115.      *    Select a different file transfer protocol.
  2116.      */
  2117.  
  2118. BYTE __regargs
  2119. ChangeProtocol(STRPTR ProtocolName,BYTE Type)
  2120. {
  2121.     UBYTE    NameBuffer[40];
  2122.     WORD    i;
  2123.  
  2124.     if(Type == XFER_DEFAULT)
  2125.     {
  2126.         ProtocolName = Config -> TransferConfig -> DefaultLibrary;
  2127.  
  2128.         Type = Config -> TransferConfig -> DefaultType;
  2129.     }
  2130.  
  2131.     if(Type == XFER_XPR)
  2132.     {
  2133.         if(!ProtocolName || !ProtocolName[0])
  2134.             ProtocolName = Config -> TransferConfig -> DefaultLibrary;
  2135.  
  2136.         if(!Stricmp(ProtocolName,LastXprLibrary) && XProtocolBase)
  2137.             return(TRUE);
  2138.     }
  2139.  
  2140.         /* Close the old library if still open. */
  2141.  
  2142.     CloseXPR();
  2143.  
  2144.     if(Type == XFER_INTERNAL)
  2145.     {
  2146.         UsesZModem = FALSE;
  2147.  
  2148.         SetTransferMenu(TRUE);
  2149.  
  2150.         strcpy(TransferProtocolName,"ASCII");
  2151.  
  2152.         return(TRUE);
  2153.     }
  2154.  
  2155.     if(Type == XFER_EXTERNALPROGRAM)
  2156.     {
  2157.         WORD i;
  2158.         STRPTR Buffer = ProtocolName;
  2159.  
  2160.         while(*Buffer == ' ')
  2161.             Buffer++;
  2162.  
  2163.         if(!Strnicmp(Buffer,"run",3))
  2164.             Buffer += 3;
  2165.  
  2166.         while(*Buffer == ' ')
  2167.             Buffer++;
  2168.  
  2169.         memcpy(NameBuffer,FilePart(Buffer),40);
  2170.  
  2171.         NameBuffer[39] = 0;
  2172.  
  2173.         for(i = 0 ; i < 40 ; i++)
  2174.         {
  2175.             if(NameBuffer[i] == ' ')
  2176.             {
  2177.                 NameBuffer[i] = 0;
  2178.  
  2179.                 break;
  2180.             }
  2181.         }
  2182.  
  2183.         strcpy(TransferProtocolName,NameBuffer);
  2184.  
  2185.         NameBuffer[0] = ToUpper(NameBuffer[0]);
  2186.  
  2187.         UsesZModem = FALSE;
  2188.  
  2189.         for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  2190.         {
  2191.             if(!Stricmp(&NameBuffer[i],"zmodem"))
  2192.                 UsesZModem = TRUE;
  2193.         }
  2194.  
  2195.         SetTransferMenu(TRUE);
  2196.  
  2197.         return(TRUE);
  2198.     }
  2199.  
  2200.         /* Clear the XPR interface buffer. */
  2201.  
  2202.     memset(XprIO,0,sizeof(struct XPR_IO));
  2203.  
  2204.         /* Copy the name of the library. */
  2205.  
  2206.     memcpy(NameBuffer,FilePart(ProtocolName),40);
  2207.     NameBuffer[39] = 0;
  2208.  
  2209.         /* Extract the name itself (strip the `.library'). */
  2210.  
  2211.     for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  2212.     {
  2213.         if(NameBuffer[i] == '.')
  2214.         {
  2215.             NameBuffer[i] = 0;
  2216.  
  2217.             break;
  2218.         }
  2219.     }
  2220.  
  2221.         /* Check if the transfer protocol is a sort of ZModem. */
  2222.  
  2223.     UsesZModem = FALSE;
  2224.  
  2225.     for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  2226.     {
  2227.         if(!Stricmp(&NameBuffer[i],"zmodem"))
  2228.             UsesZModem = TRUE;
  2229.     }
  2230.  
  2231.         /* Reset the scanner. */
  2232.  
  2233.     FlowInit(TRUE);
  2234.  
  2235.         /* Obtain the protocol default settings. */
  2236.  
  2237.     if(!GetEnvDOS(NameBuffer,ProtocolOptsBuffer))
  2238.         ProtocolOptsBuffer[0] = 0;
  2239.  
  2240.     NameBuffer[3] = ToUpper(NameBuffer[3]);
  2241.  
  2242.         /* Initialize the interface structure. */
  2243.  
  2244.     XprIO -> xpr_filename    = ProtocolOptsBuffer;
  2245.     XprIO -> xpr_fopen    = xpr_fopen;
  2246.     XprIO -> xpr_fclose    = xpr_fclose;
  2247.     XprIO -> xpr_fread    = xpr_fread;
  2248.     XprIO -> xpr_fwrite    = xpr_fwrite;
  2249.     XprIO -> xpr_sread    = xpr_sread;
  2250.     XprIO -> xpr_swrite    = xpr_swrite;
  2251.     XprIO -> xpr_sflush    = xpr_sflush;
  2252.     XprIO -> xpr_update    = xpr_update;
  2253.     XprIO -> xpr_chkabort    = xpr_chkabort;
  2254.     XprIO -> xpr_gets    = xpr_gets;
  2255.     XprIO -> xpr_setserial    = xpr_setserial;
  2256.     XprIO -> xpr_ffirst    = xpr_ffirst;
  2257.     XprIO -> xpr_fnext    = xpr_fnext;
  2258.     XprIO -> xpr_finfo    = xpr_finfo;
  2259.     XprIO -> xpr_fseek    = xpr_fseek;
  2260.     XprIO -> xpr_extension    = 4;
  2261.     XprIO -> xpr_options    = xpr_options;
  2262.     XprIO -> xpr_unlink    = xpr_unlink;
  2263.     XprIO -> xpr_squery    = xpr_squery;
  2264.     XprIO -> xpr_getptr    = xpr_getptr;
  2265.  
  2266.         /* Try to open the library. */
  2267.  
  2268.     if(XProtocolBase = (struct Library *)OpenLibrary(ProtocolName,0))
  2269.     {
  2270.             /* Set up the library. */
  2271. #ifdef ASYNC_XPR_SREAD
  2272.         ClearSerial();
  2273. #endif
  2274.         TransferBits = XProtocolSetup(XprIO);
  2275. #ifdef ASYNC_XPR_SREAD
  2276.         RestartSerial();
  2277. #endif
  2278.         DeleteTransferPanel(TRUE);
  2279.  
  2280.             /* Successful initialization? */
  2281.  
  2282.         if(TransferBits & XPRS_SUCCESS)
  2283.         {
  2284.             SetTransferMenu(TRUE);
  2285.  
  2286.             strcpy(LastXprLibrary,ProtocolName);
  2287.  
  2288.             if(TransferBits & XPRS_HOSTMON)
  2289.                 ConTransfer = ConTransferHost;
  2290.             else
  2291.                 ConTransfer = ConProcess;
  2292.  
  2293.             if(TransferBits & XPRS_HOSTNOWAIT)
  2294.             {
  2295.                 if(!HostReadBuffer)
  2296.                     HostReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
  2297.             }
  2298.             else
  2299.             {
  2300.                 if(HostReadBuffer)
  2301.                 {
  2302.                     FreeVecPooled(HostReadBuffer);
  2303.  
  2304.                     HostReadBuffer = NULL;
  2305.                 }
  2306.             }
  2307.  
  2308.             strcpy(TransferProtocolName,&NameBuffer[3]);
  2309.  
  2310.             return(TRUE);
  2311.         }
  2312.         else
  2313.         {
  2314.             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FilePart(ProtocolName));
  2315.  
  2316.             CloseLibrary(XProtocolBase);
  2317.  
  2318.             XProtocolBase = NULL;
  2319.  
  2320.             SetTransferMenu(TRUE);
  2321.  
  2322.             LastXprLibrary[0] = 0;
  2323.  
  2324.             TransferBits = 0;
  2325.  
  2326.             ConTransfer = ConProcess;
  2327.  
  2328.             TransferProtocolName[0] = 0;
  2329.         }
  2330.     }
  2331.     else
  2332.     {
  2333.         ConTransfer = ConProcess;
  2334.  
  2335.         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FilePart(ProtocolName));
  2336.  
  2337.         SetTransferMenu(TRUE);
  2338.  
  2339.         TransferBits = 0;
  2340.  
  2341.         LastXprLibrary[0] = 0;
  2342.  
  2343.         TransferProtocolName[0] = 0;
  2344.     }
  2345.  
  2346.     return(FALSE);
  2347. }
  2348.  
  2349.     /* ResetProtocol():
  2350.      *
  2351.      *    Return to the previously selected file
  2352.      *    transfer protocol.
  2353.      */
  2354.  
  2355. VOID
  2356. ResetProtocol()
  2357. {
  2358.     ChangeProtocol(NULL,XFER_DEFAULT);
  2359. }
  2360.  
  2361.     /* ProtocolSetup(BYTE IgnoreOptions):
  2362.      *
  2363.      *    Set up the library and options for the external protocol.
  2364.      */
  2365.  
  2366. BYTE __regargs
  2367. ProtocolSetup(BYTE IgnoreOptions)
  2368. {
  2369.     UBYTE    NameBuffer[40];
  2370.     WORD    i;
  2371.  
  2372.         /* Close the old library if still open. */
  2373.  
  2374.     CloseXPR();
  2375.  
  2376.     if(Config -> TransferConfig -> DefaultType == XFER_EXTERNALPROGRAM)
  2377.     {
  2378.         if(Config -> TransferConfig -> DefaultLibrary[0])
  2379.         {
  2380.             WORD i;
  2381.             STRPTR Buffer = Config -> TransferConfig -> DefaultLibrary;
  2382.  
  2383.             while(*Buffer == ' ')
  2384.                 Buffer++;
  2385.  
  2386.             if(!Strnicmp(Buffer,"run",3))
  2387.                 Buffer += 3;
  2388.  
  2389.             while(*Buffer == ' ')
  2390.                 Buffer++;
  2391.  
  2392.             memcpy(NameBuffer,FilePart(Buffer),40);
  2393.  
  2394.             NameBuffer[39] = 0;
  2395.  
  2396.             for(i = 0 ; i < 40 ; i++)
  2397.             {
  2398.                 if(NameBuffer[i] == ' ')
  2399.                 {
  2400.                     NameBuffer[i] = 0;
  2401.  
  2402.                     break;
  2403.                 }
  2404.             }
  2405.  
  2406.             NameBuffer[0] = ToUpper(NameBuffer[0]);
  2407.  
  2408.             strcpy(TransferProtocolName,NameBuffer);
  2409.  
  2410.             UsesZModem = FALSE;
  2411.  
  2412.             for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  2413.             {
  2414.                 if(!Stricmp(&NameBuffer[i],"zmodem"))
  2415.                     UsesZModem = TRUE;
  2416.             }
  2417.  
  2418.             SetTransferMenu(TRUE);
  2419.  
  2420.             return(TRUE);
  2421.         }
  2422.         else
  2423.             return(FALSE);
  2424.     }
  2425.  
  2426.         /* Clear the XPR interface buffer. */
  2427.  
  2428.     memset(XprIO,0,sizeof(struct XPR_IO));
  2429.  
  2430.         /* Copy the name of the library. */
  2431.  
  2432.     memcpy(NameBuffer,FilePart(LastXprLibrary),40);
  2433.     NameBuffer[39] = 0;
  2434.  
  2435.         /* Extract the name itself (strip the `.library'). */
  2436.  
  2437.     for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  2438.     {
  2439.         if(NameBuffer[i] == '.')
  2440.         {
  2441.             NameBuffer[i] = 0;
  2442.             break;
  2443.         }
  2444.     }
  2445.  
  2446.         /* Check if the transfer protocol is a sort of ZModem. */
  2447.  
  2448.     UsesZModem = FALSE;
  2449.  
  2450.     for(i = 0 ; i <= strlen(NameBuffer) - 6 ; i++)
  2451.     {
  2452.         if(!Stricmp(&NameBuffer[i],"zmodem"))
  2453.             UsesZModem = TRUE;
  2454.     }
  2455.  
  2456.     NameBuffer[3] = ToUpper(NameBuffer[3]);
  2457.  
  2458.         /* Reset the scanner. */
  2459.  
  2460.     FlowInit(TRUE);
  2461.  
  2462.         /* Obtain the protocol default settings. */
  2463.  
  2464.     if(!IgnoreOptions)
  2465.     {
  2466.         if(!GetEnvDOS(NameBuffer,ProtocolOptsBuffer))
  2467.             ProtocolOptsBuffer[0] = 0;
  2468.     }
  2469.  
  2470.         /* Initialize the interface structure. */
  2471.  
  2472.     XprIO -> xpr_filename    = ProtocolOptsBuffer;
  2473.     XprIO -> xpr_fopen    = xpr_fopen;
  2474.     XprIO -> xpr_fclose    = xpr_fclose;
  2475.     XprIO -> xpr_fread    = xpr_fread;
  2476.     XprIO -> xpr_fwrite    = xpr_fwrite;
  2477.     XprIO -> xpr_sread    = xpr_sread;
  2478.     XprIO -> xpr_swrite    = xpr_swrite;
  2479.     XprIO -> xpr_sflush    = xpr_sflush;
  2480.     XprIO -> xpr_update    = xpr_update;
  2481.     XprIO -> xpr_chkabort    = xpr_chkabort;
  2482.     XprIO -> xpr_gets    = xpr_gets;
  2483.     XprIO -> xpr_setserial    = xpr_setserial;
  2484.     XprIO -> xpr_ffirst    = xpr_ffirst;
  2485.     XprIO -> xpr_fnext    = xpr_fnext;
  2486.     XprIO -> xpr_finfo    = xpr_finfo;
  2487.     XprIO -> xpr_fseek    = xpr_fseek;
  2488.     XprIO -> xpr_extension    = 4;
  2489.     XprIO -> xpr_options    = xpr_options;
  2490.     XprIO -> xpr_unlink    = xpr_unlink;
  2491.     XprIO -> xpr_squery    = xpr_squery;
  2492.     XprIO -> xpr_getptr    = xpr_getptr;
  2493.  
  2494.         /* Try to open the library. */
  2495.  
  2496.     if(XProtocolBase = (struct Library *)OpenLibrary(LastXprLibrary,0))
  2497.     {
  2498.             /* Set up the library. */
  2499. #ifdef ASYNC_XPR_SREAD
  2500.         ClearSerial();
  2501. #endif
  2502.         TransferBits = XProtocolSetup(XprIO);
  2503. #ifdef ASYNC_XPR_SREAD
  2504.         RestartSerial();
  2505. #endif
  2506.         DeleteTransferPanel(IgnoreOptions != TRUE);
  2507.  
  2508.             /* Successful initialization? */
  2509.  
  2510.         if(TransferBits & XPRS_SUCCESS)
  2511.         {
  2512.             SetTransferMenu(TRUE);
  2513.  
  2514.             if(TransferBits & XPRS_HOSTMON)
  2515.                 ConTransfer = ConTransferHost;
  2516.             else
  2517.                 ConTransfer = ConProcess;
  2518.  
  2519.             if(TransferBits & XPRS_HOSTNOWAIT)
  2520.             {
  2521.                 if(!HostReadBuffer)
  2522.                     HostReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
  2523.             }
  2524.             else
  2525.             {
  2526.                 if(HostReadBuffer)
  2527.                 {
  2528.                     FreeVecPooled(HostReadBuffer);
  2529.  
  2530.                     HostReadBuffer = NULL;
  2531.                 }
  2532.             }
  2533.  
  2534.             strcpy(TransferProtocolName,&NameBuffer[3]);
  2535.  
  2536.             return(TRUE);
  2537.         }
  2538.         else
  2539.         {
  2540.             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FilePart(LastXprLibrary));
  2541.  
  2542.             CloseLibrary(XProtocolBase);
  2543.  
  2544.             XProtocolBase = NULL;
  2545.  
  2546.             LastXprLibrary[0] = 0;
  2547.  
  2548.             TransferBits = 0;
  2549.  
  2550.             ConTransfer = ConProcess;
  2551.  
  2552.             SetTransferMenu(TRUE);
  2553.  
  2554.             TransferProtocolName[0] = 0;
  2555.         }
  2556.     }
  2557.     else
  2558.     {
  2559.         ConTransfer = ConProcess;
  2560.  
  2561.         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_OPEN_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FilePart(LastXprLibrary));
  2562.  
  2563.         LastXprLibrary[0] = 0;
  2564.  
  2565.         TransferBits = 0;
  2566.  
  2567.         SetTransferMenu(TRUE);
  2568.  
  2569.         TransferProtocolName[0] = 0;
  2570.     }
  2571.  
  2572.     return(FALSE);
  2573. }
  2574.  
  2575.     /* SaveProtocolOpts():
  2576.      *
  2577.      *    Save the current protocol settings to an environment variable.
  2578.      */
  2579.  
  2580. VOID
  2581. SaveProtocolOpts()
  2582. {
  2583.         /* It's time to save the altered options. */
  2584.  
  2585.     if(NewOptions && XProtocolBase)
  2586.     {
  2587.         UBYTE    NameBuffer[40];
  2588.         WORD    i;
  2589.  
  2590.             /* Strip the `.library' part. */
  2591.  
  2592.         memcpy(NameBuffer,FilePart(LastXprLibrary),40);
  2593.         NameBuffer[39] = 0;
  2594.  
  2595.         for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
  2596.         {
  2597.             if(NameBuffer[i] == '.')
  2598.             {
  2599.                 NameBuffer[i] = 0;
  2600.                 break;
  2601.             }
  2602.         }
  2603.  
  2604.             /* Cause the xpr.library to prompt for
  2605.              * input. We expect the library to fill
  2606.              * the prompt string with the default
  2607.              * settings. The resulting string is
  2608.              * intercepted by xpr_stealopts, saved
  2609.              * to an environment variable and will
  2610.              * serve as a reinitialization string
  2611.              * later.
  2612.              */
  2613.  
  2614.         XprIO -> xpr_filename    = NULL;
  2615.         XprIO -> xpr_gets    = xpr_stealopts;
  2616.         XprIO -> xpr_extension    = 0;
  2617.         XprIO -> xpr_options    = NULL;
  2618. #ifdef ASYNC_XPR_SREAD
  2619.         ClearSerial();
  2620. #endif
  2621.         XProtocolSetup(XprIO);
  2622.  
  2623.         DeleteTransferPanel(FALSE);
  2624.  
  2625.             /* Save the options in case anything goes
  2626.              * wrong.
  2627.              */
  2628.  
  2629.         NewOptions = FALSE;
  2630.  
  2631.         SetEnvDOS(NameBuffer,ProtocolOptsBuffer);
  2632.  
  2633.             /* Reinitialize the library. */
  2634.  
  2635.         XprIO -> xpr_filename    = ProtocolOptsBuffer;
  2636.         XprIO -> xpr_gets    = xpr_gets;
  2637.         XprIO -> xpr_extension    = 4;
  2638.         XprIO -> xpr_options    = xpr_options;
  2639.  
  2640.         XProtocolSetup(XprIO);
  2641. #ifdef ASYNC_XPR_SREAD
  2642.         RestartSerial();
  2643. #endif
  2644.         DeleteTransferPanel(FALSE);
  2645.     }
  2646. }
  2647.  
  2648.     /* SelectProtocol(STRPTR Name,struct Window *ParentWindow):
  2649.      *
  2650.      *    Select a different transfer protocol library using
  2651.      *    the asl.library file requester.
  2652.      */
  2653.  
  2654. BYTE __regargs
  2655. SelectProtocol(STRPTR Name,struct Window *ParentWindow)
  2656. {
  2657.     strcpy(SharedBuffer,LastXprLibrary);
  2658.  
  2659.     if(PickFile(Window,"Libs:","xpr#?.library",LocaleString(MSG_TERMXPR_SELECT_TRANSFER_PROTOCOL_TXT),SharedBuffer,NT_LIBRARY))
  2660.     {
  2661.         if(Stricmp(SharedBuffer,LastXprLibrary))
  2662.         {
  2663.             strcpy(LastXprLibrary,SharedBuffer);
  2664.  
  2665.             return(TRUE);
  2666.         }
  2667.     }
  2668.  
  2669.     return(FALSE);
  2670. }
  2671.  
  2672.     /* TransferCleanup():
  2673.      *
  2674.      *    We did a file transfer (auto-download?) and
  2675.      *    will need to close the transfer window.
  2676.      */
  2677.  
  2678. VOID
  2679. TransferCleanup()
  2680. {
  2681.     if(DidTransfer)
  2682.     {
  2683.         if(TransferFailed || TransferError)
  2684.         {
  2685.             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2686.                 WakeUp(TransferWindow,SOUND_BADTRANSFER);
  2687.  
  2688.             DeleteTransferPanel(TRUE);
  2689.         }
  2690.         else
  2691.         {
  2692.             if(TransferWindow)
  2693.             {
  2694.                 if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2695.                     WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  2696.  
  2697.                 WaitTime(2,0);
  2698.             }
  2699.  
  2700.             DeleteTransferPanel(FALSE);
  2701.         }
  2702.  
  2703.         if(SendAbort && UsesZModem)
  2704.             SerWrite(ZModemCancel,20);
  2705.  
  2706.         SendAbort = FALSE;
  2707.  
  2708.         if(Config -> CommandConfig -> DownloadMacro[0])
  2709.             SerialCommand(Config -> CommandConfig -> DownloadMacro);
  2710.  
  2711.         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  2712.  
  2713.         DidTransfer = FALSE;
  2714.     }
  2715.     else
  2716.     {
  2717.         if(TransferFailed || TransferError)
  2718.         {
  2719.             if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2720.                 WakeUp(TransferWindow,SOUND_BADTRANSFER);
  2721.  
  2722.             DeleteTransferPanel(TRUE);
  2723.         }
  2724.         else
  2725.         {
  2726.             if(TransferWindow)
  2727.             {
  2728.                 if(Config -> TransferConfig -> TransferNotification == XFERNOTIFY_ALWAYS || Config -> TransferConfig -> TransferNotification == XFERNOTIFY_END)
  2729.                     WakeUp(TransferWindow,SOUND_GOODTRANSFER);
  2730.  
  2731.                 WaitTime(2,0);
  2732.             }
  2733.  
  2734.             DeleteTransferPanel(FALSE);
  2735.         }
  2736.     }
  2737.  
  2738.     BinaryTransfer = TRUE;
  2739.  
  2740.     Status = STATUS_READY;
  2741.  
  2742.     ReleaseWindows();
  2743. }
  2744.  
  2745.     /* RemoveUploadListItem(STRPTR Name):
  2746.      *
  2747.      *    Remove a named item from the upload list.
  2748.      */
  2749.  
  2750. VOID __regargs
  2751. RemoveUploadListItem(STRPTR Name)
  2752. {
  2753.     BPTR NameLock;
  2754.  
  2755.     if(NameLock = Lock(Name,ACCESS_READ))
  2756.     {
  2757.         struct GenericList    *List = GenericListTable[GLIST_UPLOAD];
  2758.         struct Node        *Node;
  2759.         STRPTR             Base = FilePart(Name);
  2760.  
  2761.         ObtainSemaphore(&List -> ListSemaphore);
  2762.  
  2763.         Node = (struct Node *)List -> ListHeader . mlh_Head;
  2764.  
  2765.         while(Node -> ln_Succ)
  2766.         {
  2767.             if(!Stricmp(Base,FilePart(Node -> ln_Name)))
  2768.             {
  2769.                 BPTR ListLock;
  2770.  
  2771.                 if(ListLock = Lock(Node -> ln_Name,ACCESS_READ))
  2772.                 {
  2773.                     if(SameLock(ListLock,NameLock) == LOCK_SAME)
  2774.                     {
  2775.                         Forbid();
  2776.  
  2777.                         ReleaseSemaphore(&List -> ListSemaphore);
  2778.  
  2779.                         DeleteGenericListNode(List,Node);
  2780.  
  2781.                         Permit();
  2782.  
  2783.                         UnLock(ListLock);
  2784.  
  2785.                         UnLock(NameLock);
  2786.  
  2787.                         return;
  2788.                     }
  2789.  
  2790.                     UnLock(ListLock);
  2791.                 }
  2792.             }
  2793.  
  2794.             Node = Node -> ln_Succ;
  2795.         }
  2796.  
  2797.         ReleaseSemaphore(&List -> ListSemaphore);
  2798.  
  2799.         UnLock(NameLock);
  2800.     }
  2801. }
  2802.  
  2803.     /* CloseXPR():
  2804.      *
  2805.      *    Close the XPR library if it is still open.
  2806.      */
  2807.  
  2808. VOID
  2809. CloseXPR()
  2810. {
  2811.     if(XProtocolBase)
  2812.     {
  2813.         XProtocolCleanup(XprIO);
  2814.  
  2815.         CloseLibrary(XProtocolBase);
  2816.  
  2817.         XProtocolBase = NULL;
  2818.  
  2819.         SetTransferMenu(TRUE);
  2820.  
  2821.         ConTransfer = ConProcess;
  2822.     }
  2823. }
  2824.